/*
 * @Author: wuyuxin
 * @Date: 2022-06-02 21:29:29
 * @LastEditors: wuyuxin
 * @LastEditTime: 2022-06-03 22:06:03
 * @Description:
 */
function isObject(value) {
  const valueType = typeof value;
  return value !== null && (valueType === "object" || valueType === "function");
}

function deepClone(originValue) {
  if (originValue instanceof Map) {
    return new Map([...originValue]);
  }

  if (originValue instanceof Set) {
    return new Set([...originValue]);
  }

  if (typeof originValue === "symbol") {
    return Symbol(originValue.description);
  }

  if (typeof originValue === "function") {
    return originValue;
  }

  if (!isObject(originValue)) {
    return originValue;
  }

  const newObj = Array.isArray(originValue) ? [] : {};
  for (const keys in originValue) {
    newObj[keys] = deepClone(originValue[keys]);
  }

  const sKeys = Object.getOwnPropertySymbols(originValue);
  for (const sKey of sKeys) {
    newObj[sKey] = deepClone(originValue[sKey]);
  }
  return newObj;
}

// 测试代码
let s1 = Symbol("aaa");
let s2 = Symbol("bbb");

const obj = {
  name: "why",
  age: 18,
  friend: {
    name: "james",
    address: {
      city: "广州",
    },
  },
  // 数组类型
  hobbies: ["abc", "cba", "nba"],
  // 函数类型
  foo: function (m, n) {
    console.log("foo function");
    console.log("100代码逻辑");
    return 123;
  },
  // Symbol作为key和value
  [s1]: "abc",
  s2: s2,
  // Set/Map
  set: new Set(["aaa", "bbb", "ccc"]),
  map: new Map([
    ["aaa", "abc"],
    ["bbb", "cba"],
  ]),
};

const newObj = deepClone(obj);
console.log(newObj === obj);

obj.friend.name = "kobe";
obj.friend.address.city = "成都";
console.log(newObj);
console.log(newObj.s2 === obj.s2);
